1   /*
2    * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   */
23  
24  /*
25   * @test
26   * @bug 4267450
27   * @summary Unit test for week date support
28   */
29  
30  import java.text.*;
31  import java.util.*;
32  import static java.util.GregorianCalendar.*;
33  
34  public class WeekDateTest {
35      static SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd");
36      static SimpleDateFormat ywdFormat = new SimpleDateFormat("YYYY-'W'ww-u");
37      static {
38          ymdFormat.setCalendar(newCalendar());
39          ywdFormat.setCalendar(newCalendar());
40      }
41  
42      // Round-trip Data
43      static final String[][] roundTripData = {
44          { "2005-01-01", "2004-W53-6" },
45          { "2005-01-02", "2004-W53-7" },
46          { "2005-12-31", "2005-W52-6" },
47          { "2007-01-01", "2007-W01-1" },
48          { "2007-12-30", "2007-W52-7" },
49          { "2007-12-31", "2008-W01-1" },
50          { "2008-01-01", "2008-W01-2" },
51          { "2008-12-29", "2009-W01-1" },
52          { "2008-12-31", "2009-W01-3" },
53          { "2009-01-01", "2009-W01-4" },
54          { "2009-12-31", "2009-W53-4" },
55          { "2010-01-03", "2009-W53-7" },
56          { "2009-12-31", "2009-W53-4" },
57          { "2010-01-01", "2009-W53-5" },
58          { "2010-01-02", "2009-W53-6" },
59          { "2010-01-03", "2009-W53-7" },
60          { "2008-12-28", "2008-W52-7" },
61          { "2008-12-29", "2009-W01-1" },
62          { "2008-12-30", "2009-W01-2" },
63          { "2008-12-31", "2009-W01-3" },
64          { "2009-01-01", "2009-W01-4" },
65          { "2009-01-01", "2009-W01-4" },
66      };
67  
68      // Data for leniency test
69      static final String[][] leniencyData = {
70          { "2008-12-28", "2009-W01-0" },
71          { "2010-01-04", "2009-W53-8" },
72          { "2008-12-29", "2008-W53-1" },
73      };
74  
75      static final String[] invalidData = {
76          "2010-W00-1",
77          "2010-W55-1",
78          "2010-W03-0",
79          "2010-W04-8",
80          "2010-W04-19"
81      };
82  
83      public static void main(String[] args) throws Exception {
84          formatTest(roundTripData);
85          parseTest(roundTripData);
86          parseTest(leniencyData);
87          nonLenientTest(invalidData);
88          noWeekDateSupport();
89      }
90  
91      private static void formatTest(String[][] data) throws Exception {
92          for (String[] dates : data) {
93              String regularDate = dates[0];
94              String weekDate = dates[1];
95              Date date = null;
96              date = ymdFormat.parse(regularDate);
97              String s = ywdFormat.format(date);
98              if (!s.equals(weekDate)) {
99                  throw new RuntimeException("format: got="+s+", expecetd="+weekDate);
100             }
101         }
102     }
103 
104     private static void parseTest(String[][] data) throws Exception {
105         for (String[] dates : data) {
106             String regularDate = dates[0];
107             String weekDate = dates[1];
108             Date date1 = null, date2 = null;
109             date1 = ymdFormat.parse(regularDate);
110             date2 = ywdFormat.parse(weekDate);
111             if (!date1.equals(date2)) {
112                 System.err.println(regularDate + ": date1 = " + date1);
113                 System.err.println(weekDate + ": date2 = " + date2);
114                 throw new RuntimeException("parse: date1 != date2");
115             }
116         }
117     }
118 
119 
120     // Non-lenient mode test
121     private static void nonLenientTest(String[] data) {
122         ywdFormat.setLenient(false);
123         for (String date : data) {
124             try {
125                 Date d = ywdFormat.parse(date);
126                 throw new RuntimeException("No ParseException thrown with " + date);
127             } catch (ParseException e) {
128                 // OK
129             }
130         }
131         ywdFormat.setLenient(true);
132     }
133 
134 
135     private static void noWeekDateSupport() throws Exception {
136         // Tests with Japanese Imperial Calendar that doesn't support week dates.
137         Calendar jcal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
138                                              new Locale("ja", "JP", "JP"));
139 
140         jcal.setFirstDayOfWeek(MONDAY);
141         jcal.setMinimalDaysInFirstWeek(4);
142         SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
143         sdf.setCalendar(jcal);
144         Date d = sdf.parse("21-W01-3"); // 2008-12-31 == H20-12-31
145         GregorianCalendar gcal = newCalendar();
146         gcal.setTime(d);
147         if (gcal.get(YEAR) != 2008
148             || gcal.get(MONTH) != DECEMBER
149             || gcal.get(DAY_OF_MONTH) != 31) {
150             String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected 2008-12-31%n",
151                                      gcal.get(YEAR),
152                                      gcal.get(MONTH)+1,
153                                      gcal.get(DAY_OF_MONTH));
154             throw new RuntimeException(s);
155         }
156     }
157 
158     private static GregorianCalendar newCalendar() {
159         // Use GMT to avoid any surprises related DST transitions.
160         GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
161         // Setup the ISO 8601 compatible parameters
162         cal.setFirstDayOfWeek(MONDAY);
163         cal.setMinimalDaysInFirstWeek(4);
164         return cal;
165     }
166 }